package cn.itcast.server.handler;

import cn.itcast.message.LoginRequestMessage;
import cn.itcast.message.LoginResponseMessage;
import cn.itcast.server.service.UserServiceFactory;
import cn.itcast.server.session.SessionFactory;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

/**
 * 自定义处理器 专门用来处理登录请求的,SimpleChannelInboundHandler这是一个入站处理器
 * 且通过泛型来区分我们只关注什么类型的消息(及只有匹配到的类型的消息才会进来)
 * 所以这个入站处理器只有在接收到LoginRequestMessage类型的消息时才会执行 责任链(策略模式 )
 */
@ChannelHandler.Sharable //很显然这里面并没有共享变量的存在所以不会有并发问题所以可以标注为这个 只需要一个实例给其他eventLoop共享就够了
public class LoginRequestMessageHandler extends SimpleChannelInboundHandler<LoginRequestMessage> {
    //channelRead0方法中的参数: ctx就是当前的上下文环境它里面可以拿到很多东西 例如可以拿到当前信息来源的channel等 msg就是具体的信息内容
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, LoginRequestMessage msg) throws Exception {
        //登录业务的处理
        String username = msg.getUsername();
        String password = msg.getPassword();
        boolean login = UserServiceFactory.getUserService().login(username, password);
        LoginResponseMessage responseMessage;
        if (login) {
            //登陆成功后要把用户跟channel绑定起来 不然以后聊天 你咋知道给谁聊天要发给哪个channel  这里其实就是我们自己的业务
            SessionFactory.getSession().bind(ctx.channel(), username);
            responseMessage = new LoginResponseMessage(true, "登陆成功");
        } else {
            responseMessage = new LoginResponseMessage(false, "用户名或密码错误");
        }
        ctx.writeAndFlush(responseMessage); //这里写数据出去就会触发出站处理器了 就会经过MESSAGE_CODEC去编码然后下个出站处理器等....
    }
}
